#ifndef _MS42DDC_H
#define _MS42DDC_H

#include "stdint.h"

#define MS42_CommandLen 11
// 控制类型
typedef enum _ControlType_e
{
    ControlRequest_Type = 0,
    SpeedControl = 1,
    PositionControl,
    ForceControl,
    AbsAngleControl,
} ControlType_e;

// 旋转方向
typedef enum _ControlDirection_e
{
    CCW = 0,
    CW = 1,
} ControlDirection_e;

// 细分值
typedef enum _ControlSegment_e
{
    ControlRequest_Segment = 0,
    segment2 = 2,
    segment4 = 4,
    segment8 = 8,
    segment16 = 16,
    segment32 = 32,
} ControlSegment_e;

// 多功能位
typedef union _Position_Current_AbsAngle_u
{
    uint16_t positionMult10;
    uint16_t mA;
    uint16_t absAngleMult10;
} Position_Current_AbsAngle_u;

#pragma pack(1) // 取消字节对齐
// 写入帧数据结构体
typedef struct _MS42DDCWriteCommunicate_s
{
    uint8_t head;
    uint8_t address;
    ControlType_e controlType;
    ControlDirection_e dir;
    ControlSegment_e seg;
    Position_Current_AbsAngle_u pos;
    uint16_t speed_radps;
    uint8_t BCC; // 异或校验
    uint8_t end;
} MS42WriteCommunicate_s;

// 读取帧数据结构体
typedef struct _MS42DDCReadCommunicate_s
{
    // uint8_t head;
    uint8_t address;
    uint8_t state;
    uint16_t speed;
    uint32_t angle;
    uint8_t BCC; // 异或校验
    // uint8_t end;
    uint8_t ext[2]; // 无意义，占位用
} MS42ReadCommunicate_s;
#pragma pack()

// 共用体
typedef union _MS42Data_u
{
    MS42WriteCommunicate_s write;
    MS42ReadCommunicate_s read;
    uint8_t u8[MS42_CommandLen + 1];
} MS42Data_u;

void MS42Init(void);
void MS42CycleCallback(void);
void MS42UARTTransmitCallback_Default(void);
void MS42UARTReceiveCallback(void);
void MS42SpeedModeSetSpeed(MS42Data_u *data, float speed);
void MS42SpeedModeSetSpeed_Default(float speed);
void MS42ForceModeSetCurrent(MS42Data_u *data, uint16_t ma, uint16_t speed);
void MS42ForceModeSetCurrent_Default(uint16_t ma, uint16_t speed);
void MS42AbsAngleModeSetAngle(MS42Data_u *data, float angle, float speed);
void MS42AbsAngleModeSetAngle_Default(float angle, float speed);
void MS42PositionModeSetPosition(MS42Data_u *data, float pos, float speed);
void MS42PositionModeSetPosition_Default(float pos, float speed);

#endif
